package com.salton123.imagepicker.adapter;

import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.recyclerview.widget.RecyclerView;

import com.salton123.imagepciker.R;
import com.salton123.imagepicker.ImagePicker;
import com.salton123.imagepicker.bean.ImageItem;
import com.salton123.imagepicker.custom.ImagePickerTextRepository;
import com.salton123.imagepicker.log.ILog;
import com.salton123.imagepicker.ui.ImageBaseActivity;
import com.salton123.imagepicker.ui.ImageGridActivity;
import com.salton123.imagepicker.util.ImageUtils;
import com.salton123.imagepicker.util.Utils;
import com.salton123.imagepicker.view.SuperCheckBox;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;

import static com.salton123.imagepicker.ui.ImageGridActivity.CAMERA_PERMISSION;

/**
 * 加载相册图片的RecyclerView适配器
 * <p>
 * 用于替换原项目的GridView，使用局部刷新解决选中照片出现闪动问题
 * <p>
 * 替换为RecyclerView后只是不再会导致全局刷新，
 * <p>
 * 但还是会出现明显的重新加载图片，可能是picasso图片加载框架的问题
 * <p>
 * Author: nanchen
 * Email: liushilin520@foxmail.com
 * Date: 2017-04-05  10:04
 */

public class ImageRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private static final String TAG = "ImageRecyclerAdapter";


    private static final int ITEM_TYPE_CAMERA = 0;  //第一个条目是相机
    private static final int ITEM_TYPE_IMAGE = 1;  //图片
    private static final int ITEM_TYPE_VIDEO = 2;  //视频
    private ImagePicker imagePicker;
    private Activity mActivity;
    private ArrayList<ImageItem> images;       //当前需要显示的所有的图片数据
    private ArrayList<ImageItem> mSelectedImages; //全局保存的已经选中的图片数据
    private boolean isShowCamera;         //是否显示拍照按钮
    private int mImageSize;               //每个条目的大小
    private LayoutInflater mInflater;
    private OnImageItemClickListener listener;   //图片被点击的监听

    public void setOnImageItemClickListener(OnImageItemClickListener listener) {
        this.listener = listener;
    }

    public interface OnImageItemClickListener {
        void onImageItemClick(View view, ImageItem imageItem, int position);
    }

    public void refreshData(ArrayList<ImageItem> images) {
        if (images == null || images.size() == 0) this.images = new ArrayList<>();
        else this.images = images;
        notifyDataSetChanged();
    }

    /**
     * 构造方法
     */
    public ImageRecyclerAdapter(Activity activity, ArrayList<ImageItem> images) {
        this.mActivity = activity;
        if (images == null || images.size() == 0) this.images = new ArrayList<>();
        else this.images = images;

        mImageSize = Utils.getImageItemWidth(mActivity);
        imagePicker = ImagePicker.getInstance();
        isShowCamera = imagePicker.isShowCamera();
        mSelectedImages = imagePicker.getSelectedImages();
        mInflater = LayoutInflater.from(activity);
    }

    @NotNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NotNull ViewGroup parent, int viewType) {
        if (viewType == ITEM_TYPE_CAMERA) {
            return new CameraViewHolder(mInflater.inflate(R.layout.adapter_camera_item, parent, false));
        } else if (viewType == ITEM_TYPE_VIDEO) {
            return new VideoViewHolder(mInflater.inflate(R.layout.adapter_video_list_item, parent, false));
        }
        return new ImageViewHolder(mInflater.inflate(R.layout.adapter_image_list_item, parent, false));
    }

    @Override
    public void onBindViewHolder(@NotNull RecyclerView.ViewHolder holder, int position) {
        try {
            if (holder instanceof CameraViewHolder) {
                ((CameraViewHolder) holder).bindCamera();
            } else if (holder instanceof ImageViewHolder) {
                ((ImageViewHolder) holder).bind(position);
            } else if (holder instanceof VideoViewHolder) {
                ((VideoViewHolder) holder).bind(position);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public int getItemViewType(int position) {
        ImageItem imageItem = getItem(position);
        if (isShowCamera && position == 0) {
            return ITEM_TYPE_CAMERA;
        } else if (imageItem.mimeType.startsWith("video")) {
            return ITEM_TYPE_VIDEO;
        } else {
            return ITEM_TYPE_IMAGE;
        }
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public int getItemCount() {
        return isShowCamera ? images.size() + 1 : images.size();
    }

    @Override
    public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {
        super.onViewRecycled(holder);
        if (holder instanceof ImageViewHolder) {
        }
    }

    public ImageItem getItem(int position) {
        if (isShowCamera) {
            if (position == 0) return null;
            return images.get(position - 1);
        } else {
            return images.get(position);
        }
    }

    private class ImageViewHolder extends RecyclerView.ViewHolder {

        View rootView;
        ImageView ivThumb;
        View maskSelected; // 已选中蒙层
        View checkView;
        SuperCheckBox cbCheck;
        View maskLimit; // 被限制，无法选中蒙层


        ImageViewHolder(View itemView) {
            super(itemView);
            rootView = itemView;
            ivThumb = (ImageView) itemView.findViewById(R.id.iv_thumb);
            maskSelected = itemView.findViewById(R.id.mask_selected);
            maskLimit = itemView.findViewById(R.id.view_size_limit);
            checkView = itemView.findViewById(R.id.checkView);
            cbCheck = (SuperCheckBox) itemView.findViewById(R.id.cb_check);
            itemView.setLayoutParams(new AbsListView.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT, mImageSize)); //让图片是个正方形
        }

        void bind(final int position) {
            final ImageItem imageItem = getItem(position);
            if (imageItem.size < imagePicker.getSelectSizeLimitLower()
                    || imageItem.size > imagePicker.getSelectSizeLimitUpper()) {
                ILog.d(TAG, "imageItem.size limit ");
                maskLimit.setVisibility(View.VISIBLE);
            } else {
                maskLimit.setVisibility(View.GONE);
            }
            ivThumb.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (imageItem.size < imagePicker.getSelectSizeLimitLower()) {
                        ILog.d(TAG, "onClick: imageItem.size < limit");
                        if (imagePicker.getSelectSizeLimitCallback() != null) {
                            imagePicker.getSelectSizeLimitCallback().onLimitToastLower(imageItem);
                        }
                        return;
                    }
                    if (imageItem.size > imagePicker.getSelectSizeLimitUpper()) {
                        ILog.d(TAG, "onClick: imageItem.size > limit");
                        if (imagePicker.getSelectSizeLimitCallback() != null) {
                            imagePicker.getSelectSizeLimitCallback().onLimitToastUpper(imageItem);
                        }
                        return;
                    }
                    if (listener != null) {
                        listener.onImageItemClick(rootView, imageItem, position);
                    }
                }
            });
            checkView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    ILog.d(TAG, "onClick: imageItem = " + imageItem.toString());
                    cbCheck.setChecked(!cbCheck.isChecked());
                    int selectLimit = imagePicker.getSelectLimit();
                    //数量限制
                    if (cbCheck.isChecked() && mSelectedImages.size() >= selectLimit) {
                        if (imagePicker.getSelectAmountLimitCallback() != null) {
                            imagePicker.getSelectAmountLimitCallback().onLimitToast();
                        } else {
                            Toast.makeText(mActivity.getApplicationContext(),
                                    mActivity.getString(R.string.ip_select_limit, selectLimit),
                                    Toast.LENGTH_SHORT).show();
                        }
                        cbCheck.setChecked(false); //取消选中
                        maskSelected.setVisibility(View.GONE);
                        return;
                    }
                    //大小限制
                    if (imageItem.size < imagePicker.getSelectSizeLimitLower()) {
                        ILog.d(TAG, "onClick: imageItem.size < limit");
                        if (imagePicker.getSelectSizeLimitCallback() != null) {
                            imagePicker.getSelectSizeLimitCallback().onLimitToastLower(imageItem);
                        }
                        cbCheck.setChecked(false); //取消选中
                        maskSelected.setVisibility(View.GONE);
                        return;
                    }
                    //大小限制
                    if (imageItem.size > imagePicker.getSelectSizeLimitUpper()) {
                        ILog.d(TAG, "onClick: imageItem.size > limit");
                        if (imagePicker.getSelectSizeLimitCallback() != null) {
                            imagePicker.getSelectSizeLimitCallback().onLimitToastUpper(imageItem);
                        }
                        cbCheck.setChecked(false); //取消选中
                        maskSelected.setVisibility(View.GONE);
                        return;
                    }
                    //入队
                    imagePicker.addSelectedImageItem(position, imageItem, cbCheck.isChecked());
                    maskSelected.setVisibility(cbCheck.isChecked() ? View.VISIBLE : View.GONE);
                }
            });
            //根据是否多选，显示或隐藏checkbox
            if (imagePicker.isMultiMode()) {
                cbCheck.setVisibility(View.VISIBLE);
                boolean checked = mSelectedImages.contains(imageItem);
                if (checked) {
                    maskSelected.setVisibility(View.VISIBLE);
                    cbCheck.setChecked(true);
                } else {
                    maskSelected.setVisibility(View.GONE);
                    cbCheck.setChecked(false);
                }
            } else {
                cbCheck.setVisibility(View.GONE);
            }
            if (imagePicker.getImageLoader() != null) {
                imagePicker.getImageLoader().loadImage(ivThumb, imageItem.path,
                        mImageSize, mImageSize, R.drawable.ic_default_image);
            } else {
                ImageUtils.loadImage(ivThumb, imageItem.path, mImageSize, mImageSize, R.drawable.ic_default_image);
            }
        }

    }

    private class CameraViewHolder extends RecyclerView.ViewHolder {

        View mItemView;
        TextView tvTakePhoto;

        CameraViewHolder(View itemView) {
            super(itemView);
            mItemView = itemView;
            tvTakePhoto = itemView.findViewById(R.id.tv_take_photo);
        }

        void bindCamera() {
            mItemView.setLayoutParams(new AbsListView.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT, mImageSize)); //让图a片是个正方形
            mItemView.setTag(null);
            mItemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (!((ImageBaseActivity) mActivity).checkPermission(CAMERA_PERMISSION)) {
                        ActivityCompat.requestPermissions(mActivity, CAMERA_PERMISSION,
                                ImageGridActivity.REQUEST_PERMISSION_CAMERA);
                    } else {
                        imagePicker.takePicture(mActivity, ImagePicker.REQUEST_CODE_TAKE);
                    }
                }
            });
            if (!ImagePickerTextRepository.INSTANCE.getTakePhoto().isEmpty()) {
                tvTakePhoto.setText(ImagePickerTextRepository.INSTANCE.getTakePhoto());
            }
        }
    }

    private class VideoViewHolder extends RecyclerView.ViewHolder {

        View rootView;
        ImageView ivThumb;
        View mask;
        View checkView;
        SuperCheckBox cbCheck;
        LinearLayout llBottom;
        TextView tvDuration;
        View maskLimit; // 被限制，无法选中蒙层


        VideoViewHolder(View itemView) {
            super(itemView);
            rootView = itemView;
            ivThumb = itemView.findViewById(R.id.iv_thumb);
            mask = itemView.findViewById(R.id.mask);
            checkView = itemView.findViewById(R.id.checkView);
            cbCheck = itemView.findViewById(R.id.cb_check);
            llBottom = itemView.findViewById(R.id.ll_bottom);
            tvDuration = itemView.findViewById(R.id.tv_duration);
            maskLimit = itemView.findViewById(R.id.view_size_limit);
            itemView.setLayoutParams(new AbsListView.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT, mImageSize)); //让图片是个正方形
        }

        void bind(final int position) {
            final ImageItem imageItem = getItem(position);
            //初始化无法选中蒙层
            if (imageItem.size > imagePicker.getVideoSelectSizeLimitUpper()) {
                ILog.d(TAG, "video.size limit ");
                maskLimit.setVisibility(View.VISIBLE);
            } else {
                maskLimit.setVisibility(View.GONE);
            }
            long dur = imageItem.duration;
            String durStr;
            long sec = dur / 1000;
            long min = sec / 60;
            long tSec = sec % 60;
            String secStr = tSec > 9 ? tSec + "" : "0" + tSec;
            if (min > 0) {
                long hour = min / 60;
                long tMin = min % 60;
                String minStr = tMin > 9 ? tMin + "" : "0" + tMin;
                if (hour > 0) {
                    long tHour = hour % 60;
                    durStr = (tHour > 9 ? tHour + "" : "0" + tHour) + ":" + minStr + ":" + secStr;
                } else {
                    durStr = minStr + ":" + secStr;
                }
            } else {
                durStr = "00:" + secStr;
            }
            tvDuration.setText(durStr);

            if (imagePicker.getImageLoader() != null) {
                imagePicker.getImageLoader().loadImage(ivThumb, imageItem.path,
                        mImageSize, mImageSize, R.drawable.ic_default_image);
            } else {
                ImageUtils.loadImage(ivThumb, imageItem.path, mImageSize, mImageSize, R.drawable.ic_default_image);
            }
            ivThumb.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (imageItem.size > imagePicker.getVideoSelectSizeLimitUpper()) {
                        ILog.d(TAG, "video.size limit " + imageItem.toString());
                        if (imagePicker.getVideoSelectSizeLimitCallback() != null) {
                            imagePicker.getVideoSelectSizeLimitCallback().onLimitToastUpper(imageItem);
                        }
                        return;
                    }
                    if (listener != null) {
                        listener.onImageItemClick(rootView, imageItem, position);
                    }
                }
            });
            checkView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    cbCheck.setChecked(!cbCheck.isChecked());
                    int selectLimit = imagePicker.getSelectLimit();
                    //超过数量限制
                    if (cbCheck.isChecked() && mSelectedImages.size() >= selectLimit) {
                        if (imagePicker.getSelectAmountLimitCallback() != null) {
                            imagePicker.getSelectAmountLimitCallback().onLimitToast();
                        } else {
                            Toast.makeText(mActivity.getApplicationContext(),
                                    mActivity.getString(R.string.ip_select_limit, selectLimit),
                                    Toast.LENGTH_SHORT).show();
                        }
                        cbCheck.setChecked(false);
                        mask.setVisibility(View.GONE);
                        return;
                    }
                    //超过大小限制
                    if (imageItem.size > imagePicker.getVideoSelectSizeLimitUpper()) {
                        ILog.d(TAG, "onClick: videoItem.size > limit");
                        if (imagePicker.getVideoSelectSizeLimitCallback() != null) {
                            imagePicker.getVideoSelectSizeLimitCallback().onLimitToastUpper(imageItem);
                        }
                        cbCheck.setChecked(false); //取消选中
                        mask.setVisibility(View.GONE);
                        return;
                    }
                    //符合条件，加入队列
                    imagePicker.addSelectedImageItem(position, imageItem, cbCheck.isChecked());
                    mask.setVisibility(cbCheck.isChecked() ? View.VISIBLE : View.GONE);
                }
            });
            //根据是否多选，显示或隐藏checkbox
            if (imagePicker.isMultiMode()) {
                cbCheck.setVisibility(View.VISIBLE);
                boolean checked = mSelectedImages.contains(imageItem);
                if (checked) {
                    mask.setVisibility(View.VISIBLE);
                    cbCheck.setChecked(true);
                } else {
                    mask.setVisibility(View.GONE);
                    cbCheck.setChecked(false);
                }
            } else {
                cbCheck.setVisibility(View.GONE);
            }
        }
    }
}
